package com.jeff.android.lab.widget;

import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.Nullable;

import com.jeff.android.lab.R;

/**
 * 圆形进度条
 *
 * @author: dingfeng
 * @date: 2021/5/17
 * @since: 1.0.0
 **/
public class CircularProgress extends View {

    private final int mDefaultRingColor = 0xFFEEEEEE;

    private final int mDefaultProgressColor = 0xFF057AFF;

    private final int mDefaultProgressWidth = 10;

    private final int mDefaultStartAngle = 270;

    private final int mMinWidth = 100;

    private final int mMinHeight = 100;

    private int mRingColor = mDefaultRingColor;

    private int mProgressColor = mDefaultProgressColor;

    private int mProgressWidth = mDefaultProgressWidth;

    private final Point mCenterPoint = new Point();

    private int mRadius;

    private int mStartAngle = mDefaultStartAngle; // 0~360, 默认值 270，即从 0 点开始

    private int mMaxValue = 100;

    private boolean mShowAnimate = false;

    private int mAnimateTime = 300;

    private Paint mRingPaint;

    private Paint mProgressPaint;

    private final RectF mArcRect = new RectF();

    private ValueAnimator mAnimator;

    private float mValue = 0;

    public CircularProgress(Context context) {
        this(context, null);
    }

    public CircularProgress(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, -1);
    }

    public CircularProgress(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(attrs);
    }

    private void init(AttributeSet attrs) {
        TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.CircularProgress);
        if (a != null) {
            mRingColor = a.getColor(R.styleable.CircularProgress_ring_color, mDefaultRingColor);
            mProgressColor = a.getColor(R.styleable.CircularProgress_ring_progress_color, mDefaultProgressColor);
            mProgressWidth = (int) a.getDimension(R.styleable.CircularProgress_ring_width, mDefaultProgressWidth);
            mRadius = (int) a.getDimension(R.styleable.CircularProgress_ring_radius, -1);
            mStartAngle = a.getInt(R.styleable.CircularProgress_start_angle, mDefaultStartAngle);

            mMaxValue = a.getInt(R.styleable.CircularProgress_max_value, 100);

            mShowAnimate = a.getBoolean(R.styleable.CircularProgress_show_animate, false);
            mAnimateTime = a.getInt(R.styleable.CircularProgress_animate_time, 200);

            a.recycle();
        }

        initPaint();
    }

    private void initPaint() {
        mRingPaint = new Paint();
        mRingPaint.setColor(mRingColor);
        mRingPaint.setStyle(Paint.Style.STROKE);
        mRingPaint.setStrokeWidth(mProgressWidth);
        mRingPaint.setAntiAlias(true);

        mProgressPaint = new Paint();
        mProgressPaint.setColor(mProgressColor);
        mProgressPaint.setStyle(Paint.Style.STROKE);
        mProgressPaint.setStrokeWidth(mProgressWidth);
        mProgressPaint.setAntiAlias(true);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mCenterPoint.x = w / 2;
        mCenterPoint.y = h / 2;
        mRadius = mCenterPoint.x - mProgressWidth / 2; //圆环的半径

        mArcRect.left = mCenterPoint.x - mRadius;
        mArcRect.top = mCenterPoint.y - mRadius;
        mArcRect.right = mCenterPoint.x + mRadius;
        mArcRect.bottom = mCenterPoint.y + mRadius;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        if (getLayoutParams().width == ViewGroup.LayoutParams.WRAP_CONTENT && getLayoutParams().height == ViewGroup.LayoutParams.WRAP_CONTENT) {
            setMeasuredDimension(mMinWidth, mMinHeight);
        } else if (getLayoutParams().width == ViewGroup.LayoutParams.WRAP_CONTENT) {
            setMeasuredDimension(mMinWidth, heightSize);
        } else if (getLayoutParams().height == ViewGroup.LayoutParams.WRAP_CONTENT) {
            setMeasuredDimension(widthSize, mMinHeight);
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawCircle(mCenterPoint.x, mCenterPoint.y, mRadius, mRingPaint); //画出圆环
        canvas.drawArc(mArcRect, mStartAngle, 360 * mValue / mMaxValue, false, mProgressPaint);  //根据进度画圆弧
    }

    public void setMaxValue(int maxValue) {
        mMaxValue = maxValue;
    }

    /**
     * 设置当前值
     *
     * @param value 0-max
     */
    public void setValue(int value) {
        if (value >= mMaxValue) {
            value = mMaxValue;
        }
        if (mShowAnimate) {
            startAnimator(value, mAnimateTime);
        } else {
            mValue = value;
            postInvalidate();
        }
    }

    private void startAnimator(int end, int animTime) {
        if (mAnimator == null)
            mAnimator = ValueAnimator.ofFloat(0, 1);//获取%区间 当前进度，[0.0f,1.0f]
        mAnimator.setDuration(animTime);
        mAnimator.addUpdateListener(animation -> {
            float percent = (float) animation.getAnimatedValue();
            mValue = percent * end;
            Log.d("dingfeng", "onAnimationUpdate: percent = " + percent
                    + ";value = " + mValue + "; end = " + end);
            postInvalidate();
        });
        mAnimator.start();
    }

}
